#include <iostream>
#include <mysql/mysql.h>
#include "mysqlDataBase.h"

int main()
{
#if 0
    // 初始化数据库句柄
    MYSQL *conn = mysql_init(NULL);
    if (conn == NULL)
    {
        std::cout << "mysql init failed." << std::endl;
        exit(-1);
    }

    // 连接mysql服务器
    const char *host = "localhost"; // 127.0.0.1
    const char *user = "root";
    const char *passwd = "1016";
    const char *db = "musicDB";
    unsigned int port = 3306;
    if (mysql_real_connect(conn, host, user, passwd, db, port, NULL, 0) == NULL)
    {
        std::cout << "mysql connect error" << std::endl;
        // 关闭数据库
        mysql_close(conn);
        exit(-1);
    }
    std::cout << "file:" << __FILE__ << ", line:" << __LINE__ << ":success" << std::endl;

    // 插入数据
    // const char *sql = "INSERT INTO userInfo (username, age) VALUES ('per', 10);";
    // if (mysql_query(conn, sql))
    // {
    //     std::cout << "mysql query error." << std::endl;
    //     exit(-1);
    // }

    // 查询数据
    const char *sql = "select * from userInfo;";
    // 当执行 mysql_query() 时，MySQL 服务器会处理该查询并生成一个结果集（假如是 SELECT 查询）
    if (mysql_query(conn, sql)) // 返回：0成功，非零失败
    {
        std::cout << "mysql query error." << std::endl;
        exit(-1);
    }

    // 从结果集里面拿取数据
    // mysql_store_result 函数用于从上一次执行的查询中获取结果集。
    // 如果查询没有结果集（如 INSERT、UPDATE 等语句）或者出现错误，它将返回 NULL。
    MYSQL_RES *res = mysql_store_result(conn);
    if (res == NULL)
    {
        std::cout << "get store result error:" << mysql_error(conn) << std::endl;
        // 关闭数据库
        mysql_close(conn);
        exit(-1);
    }

    // 获取列数
    unsigned int columns =  mysql_num_fields(res);
    std::cout << "columns:" << columns << std::endl;

    // 获取字段的名称
    MYSQL_FIELD *fields = mysql_fetch_fields(res);

    // 打印所有列名的信息
    for (int idx = 0; idx < columns; idx++)
    {
        std::cout << fields[idx].name << "\t";
    }
    std::cout << std::endl;

    // 获取每一行的数据
    // mysql_fetch_row(res) 函数用于从 res 结果集中逐行提取数据，并将每一行的数据赋值给 row
    // 当没有更多行时，mysql_fetch_row 返回 NULL，循环结束
    MYSQL_ROW row;
    while (row = mysql_fetch_row(res))
    {
        for (int idx = 0; idx < columns; idx++)
        {
            const char *tmp = NULL;
            if (row[idx] != NULL)
            {
                tmp = row[idx];
            }
            else
            {
                tmp = "NULL";
                // 在数据库查询结果中，当某个字段的值为空时，mysql_fetch_row 返回的 row[idx] 会是 NULL 指针，而不是字符串 "NULL"
                // 为了在输出时能清晰地标识这些空值，代码中将 NULL 值替换成了字符串 "NULL" 作为显示用的占位符
            }
            printf("%s\t", tmp);
        }
        printf("\n");
    }

    // 关闭数据库
    mysql_close(conn);
#endif

#if 0
    // 测试stdMysql类
    MySqlDataBase MySqlDB();

    // 连接数据库
    const char *dbName = "music";

    return 0;
#endif

#if 1
    // 测试事务回滚
    // 初始化数据库句柄
    MYSQL *conn = mysql_init(NULL);
    if (conn == NULL)
    {
        std::cout << "mysql init failed." << std::endl;
        exit(-1);
    }

    // 连接mysql服务器
    const char *host = "localhost"; // 127.0.0.1
    const char *user = "root";
    const char *passwd = "1016";
    const char *db = "musicDB";
    unsigned int port = 3306;
    if (mysql_real_connect(conn, host, user, passwd, db, port, NULL, 0) == NULL)
    {
        std::cout << "mysql connect error" << std::endl;
        // 关闭数据库
        mysql_close(conn);
        exit(-1);
    }
    std::cout << "file:" << __FILE__ << ", line:" << __LINE__ << ":success" << std::endl;

    // 开启事务
    if (mysql_query(conn, "START TRANSACTION;"))
    {
        std::cout << "START TRANSACTION failed." << std::endl;
        // 关闭数据库
        mysql_close(conn);
        // 退出程序
        exit(-1);
    }

    const char * sql1 = "update account set money = money - 10000 where username = 'zhangsan';";
    // const char * sql2 = "update account set money = money + 10000 where username = 'lisi';";
    const char * sql2 = "drop table account where username = 'test';";

    if (mysql_query(conn, sql1))
    {
        std::cout << "sql1 execute error." << std::endl;
        // 执行回滚
        mysql_query(conn, "ROLLBACK;");
        // 关闭数据库
        mysql_close(conn);
        // 退出程序
        exit(-1);
    }

    if (mysql_query(conn, sql2))
    {
        std::cout << "sql2 execute error." << std::endl;
        // 执行回滚
        mysql_query(conn, "ROLLBACK;");
        // 关闭数据库
        mysql_close(conn);
        // 退出程序
        exit(-1);
    }

    // 提交事务
    mysql_query(conn, "COMMIT;");
#endif
}
